package com.yunji.order.dao.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.google.common.base.Optional;
import com.yunji.common.annotation.DataScope;
import com.yunji.common.base.BaseDaoImpl;
import com.yunji.common.framework.MybatisPlusHelper;
import com.yunji.order.bo.*;
import com.yunji.order.dao.IOrderDao;
import com.yunji.order.domain.OrderDO;
import com.yunji.order.domain.OrderDetailDO;
import com.yunji.order.dto.OrderPageDTO;
import com.yunji.order.emuns.OrderStatusEnum;
import com.yunji.order.mapper.IOrderMapper;
import com.yunji.product.bo.ProductOrderBO;
import org.springframework.stereotype.Repository;
import org.springframework.util.CollectionUtils;

import java.time.LocalDate;
import java.util.List;

/**
 * @author : peter-zhu
 * @date : 2024/11/30 11:42
 * @description : TODO
 **/
@Repository
public class OrderDaoImpl extends BaseDaoImpl<IOrderMapper, OrderDO> implements IOrderDao {

    @Override
    @DataScope
    public List<OrderDO> orderPage(OrderPageDTO param) {
        LambdaQueryWrapper<OrderDO> query = new LambdaQueryWrapper<>();
        if (param.getEndedPayTime() != null)
            param.setEndedPayTime(param.getEndedPayTime().plusDays(1L));
        query.eq(param.getContainerId() != null, OrderDO::getContainerId, param.getContainerId())
                .eq(param.getLocationTypeId() != null, OrderDO::getLocationTypeId, param.getLocationTypeId())
                .like(param.getOrderCode() != null, OrderDO::getOrderCode, param.getOrderCode())
                .eq(param.getOrderStatus() != null, OrderDO::getOrderStatus, param.getOrderStatus())
                .eq(param.getSiteId() != null, OrderDO::getSiteId, param.getSiteId())
                .eq(param.getMemberId() != null, OrderDO::getMemberId, param.getMemberId())
                .like(param.getMemberPhone() != null, OrderDO::getMemberPhone, param.getMemberPhone())
                .like(param.getMemberName() != null, OrderDO::getMemberName, param.getMemberName())
                .like(param.getContainerName() != null, OrderDO::getContainerName, param.getContainerName())
                .like(param.getSiteName() != null, OrderDO::getSiteName, param.getSiteName())
                .like(param.getAgentName() != null, OrderDO::getAgentName, param.getAgentName())
                .ge(param.getBeginPayTime() != null, OrderDO::getPayTime, param.getBeginPayTime())
                .le(param.getEndedPayTime() != null, OrderDO::getPayTime, param.getEndedPayTime())
                .orderByDesc(OrderDO::getCreateTime);
        if(param.getProductId()!=null){
            query.exists(
                    MybatisPlusHelper.buildExistsSql(OrderDetailDO.class,OrderDetailDO::getOrderId,OrderDO.class,OrderDO::getOrderId)
                            + MybatisPlusHelper.addExistsSql(OrderDetailDO.class,OrderDetailDO::getProductId,param.getProductId()));

        }
        if (param.isExport())
            return list(query);
        return pageList(param, query);
    }

    @Override
    public boolean existsBySiteIds(List<Long> siteIds) {
        return lambdaQuery().in(OrderDO::getSiteId, siteIds).exists();
    }

    @Override
    public List<OrderDO> orderListByMember(ListOrderMemberBO memberBO) {
        return lambdaQuery()
                .in(!CollectionUtils.isEmpty(memberBO.getOrderStatusList()), OrderDO::getOrderStatus, memberBO.getOrderStatusList())
                .eq(memberBO.getRefund() != null, OrderDO::getRefund, memberBO.getRefund())
                .eq(OrderDO::getMemberId, memberBO.getMemberId())
                .eq(OrderDO::getReadStatus, memberBO.getReadStatus()).orderByDesc(OrderDO::getCreateTime)
                .list();
    }

    @Override
    public boolean existsQrcodeOrder(GetOrderQrcodeBO bo) {
        return lambdaQuery().eq(OrderDO::getQrCode, bo.getQrCode())
                // .eq(OrderDO::getOrdinal, bo.getOrdinal())
                .eq(OrderDO::getMemberId, bo.getMemberId())
                .eq(OrderDO::getOrderStatus, bo.getOrderStatus())
                .exists();
    }


    @Override
    public Long getOrderIdByQrcode(GetOrderQrcodeBO bo) {
        LambdaQueryWrapper<OrderDO> q = new LambdaQueryWrapper<>();
        q.eq(OrderDO::getQrCode, bo.getQrCode())
                //.eq(OrderDO::getOrdinal, bo.getOrdinal())
                .eq(OrderDO::getMemberId, bo.getMemberId())
                .eq(OrderDO::getOrderStatus, bo.getOrderStatus());
        return Optional.fromNullable(getOne(q)).transform(OrderDO::getOrderId).orNull();
    }

    @Override
    public Integer countProductOrderSale(ProductOrderBO bo) {
        return lambdaQuery()
                //  .eq(BeanUtils.isNotNull(bo.getProductId()),OrderDO::getProductId,bo.getProductId())
                .in(OrderDO::getOrderStatus, OrderStatusEnum.PAY_SUCCESS.getCode()).count().intValue();
    }

    @Override
    public Long getOrderId(ExistsOrderBO build) {
        LambdaQueryWrapper<OrderDO> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(OrderDO::getOrderStatus, build.getOrderStatus())
                .eq(OrderDO::getContainerId, build.getContainerId());
        return Optional.fromNullable(getOne(wrapper)).transform(OrderDO::getOrderId).orNull();
    }


    @Override
    public boolean existsOrder(ExistsOrderBO existsOrderBO) {
        return lambdaQuery()
                .in(existsOrderBO.getStatusList() != null, OrderDO::getOrderStatus, existsOrderBO.getStatusList())
                .eq(existsOrderBO.getAgentId() != null, OrderDO::getAgentId, existsOrderBO.getAgentId())
                .eq(existsOrderBO.getContainerId() != null, OrderDO::getContainerId, existsOrderBO.getContainerId())
                .eq(existsOrderBO.getOrderStatus() != null, OrderDO::getOrderStatus, existsOrderBO.getOrderStatus())
                .exists();
    }

    @Override
    public OrderDO getOrderByCode(String orderCode) {
        return lambdaQuery().eq(OrderDO::getOrderCode, orderCode).one();
    }


    @Override
    public List<OrderDO> searchOrderStatus(List<Integer> statusList) {
        return lambdaQuery().in(OrderDO::getOrderStatus, statusList).list();
    }

    @Override
    public List<OrderDO> listScaleOrder(ListScaleOrderBO bo) {
        return lambdaQuery().select(OrderDO::getOrderId, OrderDO::getOrderCode,
                        OrderDO::getOrderStatus, OrderDO::getCreateTime, OrderDO::getPayCode, OrderDO::getOpenId)
                .eq(OrderDO::getFrozen, bo.getFrozen()).eq(OrderDO::getOrderStatus, bo.getOrderStatus())
                .le(OrderDO::getCreateTime,bo.getTime()).list();
    }

    @Override
    public List<OrderDO> listDeliveryOrder(ListDeliveryOrderBO bo) {
        return lambdaQuery().select(OrderDO::getOrderId, OrderDO::getOrderCode, OrderDO::getOrderStatus,
                        OrderDO::getCreateTime, OrderDO::getPayCode, OrderDO::getOpenId)
                .eq(OrderDO::getSendProduct, bo.getSendProduct()).eq(OrderDO::getOrderStatus, bo.getOrderStatus())
                .le(OrderDO::getCreateTime,bo.getTime()).list();
    }

    @Override
    public boolean updateOrderStatus(OrderModifyStatusBO bo) {
        return modifyStatusById(bo, OrderDO::getOrderId, OrderDO::getOrderStatus);
    }
}
